Skip to content

feat(workflow-controller): coordinate one workflow run - #107

Open
xyh202131 wants to merge 3 commits into
1024XEngineer:mainfrom
xyh202131:feat/workflow-controller-coordinator
Open

feat(workflow-controller): coordinate one workflow run#107
xyh202131 wants to merge 3 commits into
1024XEngineer:mainfrom
xyh202131:feat/workflow-controller-coordinator

Conversation

@xyh202131

@xyh202131 xyh202131 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

目的

按导师确认的边界重建 WorkflowController:一个 Controller 实例只对应一条 WorkflowRun。entities 只提供纯数据与异步 CRUD;Controller 同时持有当前 Run 快照,并向 Quick Start 与 Workflow Editor 提供相同的业务方法。

当前设计

  • Quick Start 自动连续调用,Workflow Editor 等待用户逐步点击;两套界面不同,但共用同一套节点推进规则。
  • WorkflowRun 直接保存 nodes,节点间的边由 dependsOnNodeIds 表达,不再存在 root、step、revision、driver 或本地 Store。
  • Character 通过后会按显式依赖边同时解锁多个 Action;互不依赖的 Action 可以并行生成。
  • Controller 提供添加 Action、生成/确认角色、生成/确认动作首帧、生成 32 帧动画、审核通过、重做、中断与恢复等业务方法。
  • WorkflowRun 只在后端 update 成功后替换内存快照;保存失败不会向页面暴露未落库的假状态。
  • Generation 使用 nodeId + taskId + role 绑定目标;恢复时只查询当前 phase 对应的任务,旧首帧任务不会把动画阶段倒退。
  • SSE 先订阅再查询,避免查询与订阅之间漏掉终态;SSE 与 GET 同时返回终态时只保存一次。
  • 节点重做使用执行代次隔离,Generation.create() 尚未返回时产生的旧任务不能重新挂回新执行线。
  • Generation 已创建但任务引用保存失败时,本 Controller 实例会保留待附加记录,重试复用同一任务。
  • 后端没有 cancel,interrupt() 只停止前端自动处理和订阅;resume() 查询任务快照后继续,不伪装服务端任务已取消。
  • spriteWidth / spriteHeight 已进入正式 Generation 输入契约,避免真实适配器静默丢弃项目尺寸。

范围

本 PR 只包含:

不包含页面、Playtest、Publish、导出、后端实现或登录模块。此前误合入的重复目录和整包前后端快照均已移除。

验证

  • Controller 定向测试:13 项通过
  • 前端全量测试:23 个测试文件、137 项通过
  • TypeScript:通过
  • Lint:通过
  • 生产构建:通过
  • 格式检查:通过
  • git diff --check:通过

后端约束

如果 Generation 已创建、WorkflowRun 引用保存持续失败且用户立刻整页刷新,前端无法跨进程找回未绑定任务。要做到跨刷新绝对不重复,需要后端后续提供幂等键或原子创建/绑定能力;当前实现已经保证同一 Controller 生命周期内不会重复创建。

Depends on #86
Closes #106

@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
windup Error Error Aug 7, 2026 10:35am

@xyh202131
xyh202131 marked this pull request as ready for review August 4, 2026 06:45

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three concrete issues keep this flow from being reliable as-is.

}

const taskIds = requireStep(run, 'first-frame').candidateTaskIds
const terminals = await Promise.all(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High: waitForTerminal subscribes only after it has already observed a non-terminal snapshot. If the generation completes in the gap between get() and subscribe(), that terminal event is missed and the promise can hang forever, which leaves start*/resume* calls stuck.

nextType: WorkflowStepType,
updatedAt: string,
): WorkflowRun {
return editCurrentRevision(run, updatedAt, (revision) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High: this helper advances the current revision without checking whether the run was interrupted meanwhile. interruptRun() only flips the run status, so an in-flight generation that finishes later can still move an interrupted workflow forward behind the user's back.

if (current.status !== expectedRevisionStatus) return false
if (revisions.slice(0, -1).some((revision) => revision.status === 'active')) return false

// 运行中/已中断保留唯一当前步骤;终态不得继续挂着 active 步骤。

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium: the terminal-state check only looks for active steps. A completed run can still contain failed steps and pass validation, so corrupted or partially failed history can be hydrated/saved as if it were valid.

@xyh202131
xyh202131 force-pushed the feat/workflow-controller-coordinator branch from 98daef0 to 2f73825 Compare August 7, 2026 07:37
@xyh202131 xyh202131 changed the title feat(workflow-controller): add resumable workflow coordination feat(workflow-controller): coordinate one workflow run Aug 7, 2026
@1024XEngineer 1024XEngineer deleted a comment from huyanxius Aug 7, 2026
@xyh202131

Copy link
Copy Markdown
Contributor Author

@fennoai 复审

@fennoai

fennoai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Re-review Result

Found 1 issue on the updated PR.

  • Medium frontend/src/entities/workflow-run/api.ts:85: the WorkflowRun response validator accepts nodes whose status and phase contradict each other. For example, a character node with status: 'passed', phase: 'configuring_character', and selectedImageUrl: null passes validation because the selected image is required only when phase === 'completed'. The controller treats dependencies as satisfied solely via status === 'passed', so a corrupted persisted node can unlock downstream Action nodes without the confirmed character asset. Please make the validator enforce the status/phase matrix, especially passed => phase: 'completed' plus the selected asset, and add a regression test for this mismatch.

Verification:

  • Reviewed the fixed range ab6e8d1e31385bcccc9cd9c18b38469fd4b4a22b...2f73825642a0954c3536f0b247a27c16b7c84e99.
  • Confirmed the prior FennoAI findings were against an outdated file and the replacement controller addresses the subscription-before-GET and interrupt settlement races.
  • git diff --check passed locally.
  • Focused local Vitest run could not start in this checkout: vitest: Permission denied, with no local node_modules/vitest present. Collected GitHub checks for the head commit are green, including frontend checks and lint/test.

View job run

* 调用、后者等待用户逐步点击。Controller 不识别入口,也不保存第二份流程模型。
*/
export interface WorkflowController {
create(input: CreateWorkflowRunInput): Promise<WorkflowRun>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有基于这套接口试着写一下 UI(如 Quick Start)那边的代码吗,会长成什么样?

问这个主要是发现这个 controller 不仅提供了 getWorkflow 用于读取 WorkflowRun 数据,还会让每一个修改方法也都返回 WorkflowRun 数据;我不确定哪个是使用方主要的获取 workflow-run 数据的渠道

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

另外上面 AI review comment 记得处理 & resolve 下

…tion-full-frame)

- Replace template-candidate/action-generation with action-first-frame/action-full-frame
- confirmCandidate → confirmFirstFrame
- Update all state transitions and tests

Co-Authored-By: Claude <noreply@anthropic.com>
@xyh202131
xyh202131 force-pushed the feat/workflow-controller-coordinator branch from 82ad6e4 to f603a04 Compare August 7, 2026 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: 实现 WorkflowController 创作协调与恢复边界(Refs #37)

2 participants